package com.gitee.wsl.prism4j.languages

import com.gitee.wsl.prism4j.Prism4j
import com.gitee.wsl.prism4j.Prism4j.Companion.grammar
import com.gitee.wsl.prism4j.Prism4j.Companion.pattern
import com.gitee.wsl.prism4j.Prism4j.Companion.token
import com.gitee.wsl.prism4j.annotations.Aliases
import com.gitee.wsl.prism4j.Prism4j.Pattern

@Suppress("unused")
@Aliases("xml", "html", "mathml", "svg")
object Prism_markup {
    fun create(prism4j: Prism4j): Prism4j.Grammar {
        val entity: Prism4j.Token = token("entity", pattern(Pattern.compile("&#?[\\da-z]{1,8};", Pattern.CASE_INSENSITIVE)))
        return grammar(
            "markup",
            token("comment", pattern(Pattern.compile("<!--[\\s\\S]*?-->"))),
            token("prolog", pattern(Pattern.compile("<\\?[\\s\\S]+?\\?>"))),
            token("doctype", pattern(Pattern.compile("<!DOCTYPE[\\s\\S]+?>", Pattern.CASE_INSENSITIVE))),
            token("cdata", pattern(Pattern.compile("<!\\[CDATA\\[[\\s\\S]*?]]>", Pattern.CASE_INSENSITIVE))),
            token(
                "tag",
                pattern(
                    Pattern.compile(
                        "<\\/?(?!\\d)[^\\s>\\/=$<%]+(?:\\s+[^\\s>\\/=]+(?:=(?:(\"|')(?:\\\\[\\s\\S]|(?!\\1)[^\\\\])*\\1|[^\\s'\">=]+))?)*\\s*\\/?>",
                        Pattern.CASE_INSENSITIVE
                    ),
                    false,
                    true,
                    null,
                    grammar(
                        "inside",
                        token(
                            "tag",
                            pattern(
                                Pattern.compile("^<\\/?[^\\s>\\/]+", Pattern.CASE_INSENSITIVE),
                                false,
                                false,
                                null,
                                grammar(
                                    "inside",
                                    token("punctuation", pattern(Pattern.compile("^<\\/?"))),
                                    token("namespace", pattern(Pattern.compile("^[^\\s>\\/:]+:")))
                                )
                            )
                        ),
                        token(
                            "attr-value",
                            pattern(
                                Pattern.compile(
                                    "=(?:(\"|')(?:\\\\[\\s\\S]|(?!\\1)[^\\\\])*\\1|[^\\s'\">=]+)",
                                    Pattern.CASE_INSENSITIVE
                                ),
                                false,
                                false,
                                null,
                                grammar(
                                    "inside",
                                    token(
                                        "punctuation",
                                        pattern(Pattern.compile("^=")),
                                        pattern(Pattern.compile("(^|[^\\\\])[\"']"), true)
                                    ),
                                    entity
                                )
                            )
                        ),
                        token("punctuation", pattern(Pattern.compile("\\/?>"))),
                        token(
                            "attr-name",
                            pattern(
                                Pattern.compile("[^\\s>\\/]+"),
                                false,
                                false,
                                null,
                                grammar(
                                    "inside",
                                    token("namespace", pattern(Pattern.compile("^[^\\s>\\/:]+:")))
                                )
                            )
                        )
                    )
                )
            ),
            entity
        )
    }
}
